import { Tabs, Tab } from 'nextra/components'

# RTL support

If you want to support the `dir` attribute in your `<html>` tag, you'll need to add some logic:

## From the root layout

```tsx {3,6}
// app/[locale]/layout.tsx
export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
  const dir = new Intl.Locale(locale).getTextInfo().direction

  return (
    <html lang={locale} dir={dir}>
      <body>
        {children}
      </body>
    </html>
  )
}
```

### Caveat

Note that this won't work in Firefox if your root layout is a Client Component. This is because the `Intl.Locale.prototype.getTextInfo` API is [not yet supported in Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getTextInfo#browser_compatibility).

To prevent this, you can add a polyfill to guarantee compatibility with all browsers, until this standard is fully adopted. First, install the `intl-locale-textinfo-polyfill` package:

<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
  <Tab>
    ```bash
    pnpm install intl-locale-textinfo-polyfill
    ```
  </Tab>
  <Tab>
    ```bash
    npm install intl-locale-textinfo-polyfill
    ```
  </Tab>
  <Tab>
    ```bash
    yarn add intl-locale-textinfo-polyfill
    ```
  </Tab>
    <Tab>
    ```bash
    bun add intl-locale-textinfo-polyfill
    ```
  </Tab>
</Tabs>

Then, use it instead of the native `Intl.Locale.prototype.getTextInfo` API:

```tsx {2,5}
// app/[locale]/layout.tsx
import Locale from 'intl-locale-textinfo-polyfill'

export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
  const { direction: dir } = new Locale(locale).textInfo

  return (
    <html lang={locale} dir={dir}>
      <body>
        {children}
      </body>
    </html>
  )
}
```

## With a useEffect call

You may implement your RTL support with a `useEffect` as well. For instance, if you have a language switcher component on all your pages, you could also choose to write the language direction detection logic in it:

```tsx {11-13}
// LanguageSwitcher.tsx
'use client'

import { useChangeLocale, useCurrentLocale } from '../../locales/client'
import { FunctionComponent, useEffect } from 'react'

export default function LanguageSwitcher() {
  const currentLocale = useCurrentLocale()
  const changeLocale = useChangeLocale()

  useEffect(() => {
    document.documentElement.dir = isLocaleRTL(currentLocale) ? 'rtl' : 'ltr'
  }, [currentLocale])

  return (
    <div className="flex flex-col gap-4">
      <button onClick={() => changeLocale('en')}>EN</Button>
      <button onClick={() => changeLocale('fr')}>FR</Button>
    </div>
  )
}
```

Where `isLocaleRTL` could be a call to a librarie like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers.

### Caveat

Note that this choice of implementation will cause an UI flickering when your user loads your web pages for the first time: the page will first be mounted with the default `dir` attribute value of your HTML node, then updates when the component including the `useEffect` is mounted. This will introduce CLS (Cumulative Layout Shift) issues.
